use std::arch::x86_64::*;
use crate::compute::parallel::simd_advanced::CpuFeatures;

/// 缓存行大小(字节)
const CACHE_LINE_SIZE: usize = 64;

// 已有的结构体定义...
#[derive(Debug)]
pub struct RsiResult {
    pub rsi: Vec<f64>,
    pub avg_gain: Vec<f64>,
    pub avg_loss: Vec<f64>,
}

#[derive(Debug)]
pub struct StochasticResult {
    pub k: Vec<f64>,
    pub d: Vec<f64>,
}

#[derive(Debug)]
pub struct MomentumResult {
    pub momentum: Vec<f64>,
    pub rate_of_change: Vec<f64>,
}

/// 布林带计算结果
#[derive(Debug)]
pub struct BollingerResult {
    pub middle: Vec<f64>,
    pub upper: Vec<f64>,
    pub lower: Vec<f64>,
}

/// MACD计算结果
#[derive(Debug)]
pub struct MacdResult {
    pub macd: Vec<f64>,
    pub signal: Vec<f64>,
    pub histogram: Vec<f64>,
}

/// 平均真实范围(ATR)计算结果
#[derive(Debug)]
pub struct AtrResult {
    pub tr: Vec<f64>,
    pub atr: Vec<f64>,
}

// 缓存预热器和内存对齐向量的实现保持不变...
pub struct CacheWarmer {
    buffer: Vec<u8>,
}

impl CacheWarmer {
    pub fn new(size: usize) -> Self {
        CacheWarmer {
            buffer: vec![0; size],
        }
    }

    pub fn warm(&mut self) {
        for i in (0..self.buffer.len()).step_by(CACHE_LINE_SIZE) {
            self.buffer[i] = 1;
        }
    }
}

#[repr(align(64))]
pub struct AlignedVec {
    data: Vec<f64>,
}

impl AlignedVec {
    pub fn new(size: usize) -> Self {
        let mut vec = Vec::with_capacity(size);
        vec.resize(size, 0.0);
        AlignedVec { data: vec }
    }

    pub fn as_slice(&self) -> &[f64] {
        &self.data
    }

    pub fn as_mut_slice(&mut self) -> &mut [f64] {
        &mut self.data
    }
}

// 新增技术指标实现...

/// AVX-512优化的布林带计算
#[cfg(target_arch = "x86_64")]
pub unsafe fn compute_bollinger_avx512(
    data: &[f64],
    period: usize,
    num_std_dev: f64,
) -> BollingerResult {
    if !is_x86_feature_detected!("avx512f") {
        return compute_bollinger_fallback(data, period, num_std_dev);
    }

    let len = data.len();
    let mut middle = AlignedVec::new(len);
    let mut upper = AlignedVec::new(len);
    let mut lower = AlignedVec::new(len);

    // 预热缓存
    let mut warmer = CacheWarmer::new(CACHE_LINE_SIZE * 3);
    warmer.warm();

    let period_f64 = _mm512_set1_pd(period as f64);
    let num_std_dev_vec = _mm512_set1_pd(num_std_dev);

    for i in (period-1..len).step_by(8) {
        let mut sum = _mm512_setzero_pd();
        let mut sum_sq = _mm512_setzero_pd();

        // 计算移动窗口的和与平方和
        for j in 0..period {
            let values = _mm512_loadu_pd(&data[i-period+1+j]);
            sum = _mm512_add_pd(sum, values);
            sum_sq = _mm512_fmadd_pd(values, values, sum_sq);
        }

        // 计算均值
        let mean = _mm512_div_pd(sum, period_f64);
        _mm512_storeu_pd(&mut middle.as_mut_slice()[i], mean);

        // 计算标准差
        let variance = _mm512_div_pd(
            _mm512_sub_pd(
                sum_sq,
                _mm512_mul_pd(sum, _mm512_div_pd(sum, period_f64))
            ),
            period_f64
        );
        let std_dev = _mm512_sqrt_pd(variance);

        // 计算上下轨
        let band = _mm512_mul_pd(std_dev, num_std_dev_vec);
        let upper_band = _mm512_add_pd(mean, band);
        let lower_band = _mm512_sub_pd(mean, band);

        _mm512_storeu_pd(&mut upper.as_mut_slice()[i], upper_band);
        _mm512_storeu_pd(&mut lower.as_mut_slice()[i], lower_band);
    }

    BollingerResult {
        middle: middle.data,
        upper: upper.data,
        lower: lower.data,
    }
}

/// AVX-512优化的MACD计算
#[cfg(target_arch = "x86_64")]
pub unsafe fn compute_macd_avx512(
    data: &[f64],
    fast_period: usize,
    slow_period: usize,
    signal_period: usize,
) -> MacdResult {
    if !is_x86_feature_detected!("avx512f") {
        return compute_macd_fallback(data, fast_period, slow_period, signal_period);
    }

    let len = data.len();
    let mut fast_ema = AlignedVec::new(len);
    let mut slow_ema = AlignedVec::new(len);
    let mut macd = AlignedVec::new(len);
    let mut signal = AlignedVec::new(len);
    let mut histogram = AlignedVec::new(len);

    // 预热缓存
    let mut warmer = CacheWarmer::new(CACHE_LINE_SIZE * 5);
    warmer.warm();

    // 计算快速EMA的平滑系数
    let fast_alpha = 2.0 / (fast_period as f64 + 1.0);
    let fast_alpha_vec = _mm512_set1_pd(fast_alpha);
    let fast_complement = _mm512_set1_pd(1.0 - fast_alpha);

    // 计算慢速EMA的平滑系数
    let slow_alpha = 2.0 / (slow_period as f64 + 1.0);
    let slow_alpha_vec = _mm512_set1_pd(slow_alpha);
    let slow_complement = _mm512_set1_pd(1.0 - slow_alpha);

    // 计算信号线的平滑系数
    let signal_alpha = 2.0 / (signal_period as f64 + 1.0);
    let signal_alpha_vec = _mm512_set1_pd(signal_alpha);
    let signal_complement = _mm512_set1_pd(1.0 - signal_alpha);

    // 初始化EMA值
    fast_ema.as_mut_slice()[0] = data[0];
    slow_ema.as_mut_slice()[0] = data[0];

    // 使用AVX-512计算MACD
    for i in (1..len).step_by(8) {
        let price = _mm512_loadu_pd(&data[i]);
        let prev_fast = _mm512_loadu_pd(&fast_ema.as_slice()[i-1]);
        let prev_slow = _mm512_loadu_pd(&slow_ema.as_slice()[i-1]);

        // 计算快速和慢速EMA
        let new_fast = _mm512_fmadd_pd(
            _mm512_sub_pd(price, prev_fast),
            fast_alpha_vec,
            prev_fast
        );
        let new_slow = _mm512_fmadd_pd(
            _mm512_sub_pd(price, prev_slow),
            slow_alpha_vec,
            prev_slow
        );

        _mm512_storeu_pd(&mut fast_ema.as_mut_slice()[i], new_fast);
        _mm512_storeu_pd(&mut slow_ema.as_mut_slice()[i], new_slow);

        // 计算MACD线
        let macd_line = _mm512_sub_pd(new_fast, new_slow);
        _mm512_storeu_pd(&mut macd.as_mut_slice()[i], macd_line);

        // 计算信号线
        if i >= signal_period {
            let prev_signal = _mm512_loadu_pd(&signal.as_slice()[i-1]);
            let new_signal = _mm512_fmadd_pd(
                _mm512_sub_pd(macd_line, prev_signal),
                signal_alpha_vec,
                prev_signal
            );
            _mm512_storeu_pd(&mut signal.as_mut_slice()[i], new_signal);

            // 计算柱状图
            let hist = _mm512_sub_pd(macd_line, new_signal);
            _mm512_storeu_pd(&mut histogram.as_mut_slice()[i], hist);
        }
    }

    MacdResult {
        macd: macd.data,
        signal: signal.data,
        histogram: histogram.data,
    }
}

/// AVX-512优化的ATR计算
#[cfg(target_arch = "x86_64")]
pub unsafe fn compute_atr_avx512(
    high: &[f64],
    low: &[f64],
    close: &[f64],
    period: usize,
) -> AtrResult {
    if !is_x86_feature_detected!("avx512f") {
        return compute_atr_fallback(high, low, close, period);
    }

    let len = close.len();
    let mut tr = AlignedVec::new(len);
    let mut atr = AlignedVec::new(len);

    // 预热缓存
    let mut warmer = CacheWarmer::new(CACHE_LINE_SIZE * 2);
    warmer.warm();

    // 计算第一个TR值
    tr.as_mut_slice()[0] = high[0] - low[0];

    // 使用AVX-512计算TR值
    for i in (1..len).step_by(8) {
        let high_price = _mm512_loadu_pd(&high[i]);
        let low_price = _mm512_loadu_pd(&low[i]);
        let close_prev = _mm512_loadu_pd(&close[i-1]);

        // 计算三个差值
        let hl = _mm512_sub_pd(high_price, low_price);
        let hc = _mm512_sub_pd(high_price, close_prev);
        let lc = _mm512_sub_pd(close_prev, low_price);

        // 取绝对值
        let abs_hc = _mm512_abs_pd(hc);
        let abs_lc = _mm512_abs_pd(lc);

        // 找出最大值
        let max_hl_hc = _mm512_max_pd(hl, abs_hc);
        let tr_values = _mm512_max_pd(max_hl_hc, abs_lc);

        _mm512_storeu_pd(&mut tr.as_mut_slice()[i], tr_values);
    }

    // 计算ATR
    let period_f64 = _mm512_set1_pd(period as f64);
    let multiplier = _mm512_set1_pd((period - 1) as f64 / period as f64);

    // 计算第一个ATR值
    let mut first_atr = 0.0;
    for i in 0..period {
        first_atr += tr.as_slice()[i];
    }
    first_atr /= period as f64;
    atr.as_mut_slice()[period-1] = first_atr;

    // 使用AVX-512计算后续的ATR值
    for i in (period..len).step_by(8) {
        let prev_atr = _mm512_loadu_pd(&atr.as_slice()[i-1]);
        let curr_tr = _mm512_loadu_pd(&tr.as_slice()[i]);

        // ATR = ((period-1) * prev_ATR + TR) / period
        let new_atr = _mm512_fmadd_pd(
            prev_atr,
            multiplier,
            _mm512_div_pd(curr_tr, period_f64)
        );

        _mm512_storeu_pd(&mut atr.as_mut_slice()[i], new_atr);
    }

    AtrResult {
        tr: tr.data,
        atr: atr.data,
    }
}

// 标量版本的后备实现...

fn compute_bollinger_fallback(
    data: &[f64],
    period: usize,
    num_std_dev: f64,
) -> BollingerResult {
    let len = data.len();
    let mut middle = vec![0.0; len];
    let mut upper = vec![0.0; len];
    let mut lower = vec![0.0; len];

    for i in period-1..len {
        let mut sum = 0.0;
        let mut sum_sq = 0.0;

        for j in 0..period {
            let value = data[i-period+1+j];
            sum += value;
            sum_sq += value * value;
        }

        let mean = sum / period as f64;
        let variance = (sum_sq - sum * sum / period as f64) / period as f64;
        let std_dev = variance.sqrt();

        middle[i] = mean;
        upper[i] = mean + num_std_dev * std_dev;
        lower[i] = mean - num_std_dev * std_dev;
    }

    BollingerResult {
        middle,
        upper,
        lower,
    }
}

fn compute_macd_fallback(
    data: &[f64],
    fast_period: usize,
    slow_period: usize,
    signal_period: usize,
) -> MacdResult {
    let len = data.len();
    let mut fast_ema = vec![0.0; len];
    let mut slow_ema = vec![0.0; len];
    let mut macd = vec![0.0; len];
    let mut signal = vec![0.0; len];
    let mut histogram = vec![0.0; len];

    // 初始化EMA值
    fast_ema[0] = data[0];
    slow_ema[0] = data[0];

    let fast_alpha = 2.0 / (fast_period as f64 + 1.0);
    let slow_alpha = 2.0 / (slow_period as f64 + 1.0);
    let signal_alpha = 2.0 / (signal_period as f64 + 1.0);

    for i in 1..len {
        // 计算快速和慢速EMA
        fast_ema[i] = data[i] * fast_alpha + fast_ema[i-1] * (1.0 - fast_alpha);
        slow_ema[i] = data[i] * slow_alpha + slow_ema[i-1] * (1.0 - slow_alpha);

        // 计算MACD线
        macd[i] = fast_ema[i] - slow_ema[i];

        // 计算信号线和柱状图
        if i >= signal_period {
            signal[i] = macd[i] * signal_alpha + signal[i-1] * (1.0 - signal_alpha);
            histogram[i] = macd[i] - signal[i];
        }
    }

    MacdResult {
        macd,
        signal,
        histogram,
    }
}

fn compute_atr_fallback(
    high: &[f64],
    low: &[f64],
    close: &[f64],
    period: usize,
) -> AtrResult {
    let len = close.len();
    let mut tr = vec![0.0; len];
    let mut atr = vec![0.0; len];

    // 计算TR值
    tr[0] = high[0] - low[0];
    for i in 1..len {
        let hl = high[i] - low[i];
        let hc = (high[i] - close[i-1]).abs();
        let lc = (close[i-1] - low[i]).abs();
        tr[i] = hl.max(hc).max(lc);
    }

    // 计算第一个ATR值
    let mut first_atr = 0.0;
    for i in 0..period {
        first_atr += tr[i];
    }
    first_atr /= period as f64;
    atr[period-1] = first_atr;

    // 计算后续的ATR值
    for i in period..len {
        atr[i] = (atr[i-1] * (period - 1) as f64 + tr[i]) / period as f64;
    }

    AtrResult { tr, atr }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_bollinger_bands() {
        let data = vec![
            44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42,
            45.84, 46.08, 45.89, 46.03, 45.61, 46.28, 46.28, 46.00
        ];

        unsafe {
            let result = compute_bollinger_avx512(&data, 10, 2.0);
            assert!(result.middle.len() == data.len());
            assert!(result.upper.len() == data.len());
            assert!(result.lower.len() == data.len());

            // 验证上轨必须大于中轨，下轨必须小于中轨
            for i in 10..data.len() {
                assert!(result.upper[i] > result.middle[i]);
                assert!(result.lower[i] < result.middle[i]);
            }
        }
    }

    #[test]
    fn test_macd() {
        let data = vec![
            44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42,
            45.84, 46.08, 45.89, 46.03, 45.61, 46.28, 46.28, 46.00
        ];

        unsafe {
            let result = compute_macd_avx512(&data, 12, 26, 9);
            assert!(result.macd.len() == data.len());
            assert!(result.signal.len() == data.len());
            assert!(result.histogram.len() == data.len());
        }
    }

    #[test]
    fn test_atr() {
        let high = vec![
            48.70, 48.72, 48.90, 48.87, 48.82, 49.05, 49.20, 49.35,
            49.92, 50.19, 50.12, 49.66, 49.88, 50.19, 50.36, 50.57
        ];
        let low = vec![
            47.79, 48.14, 48.39, 48.37, 48.24, 48.64, 48.94, 48.86,
            49.50, 49.87, 49.20, 48.90, 49.43, 49.73, 49.26, 50.09
        ];
        let close = vec![
            48.16, 48.61, 48.75, 48.63, 48.74, 49.03, 49.07, 49.32,
            49.91, 50.13, 49.53, 49.50, 49.75, 50.03, 50.31, 50.52
        ];

        unsafe {
            let result = compute_atr_avx512(&high, &low, &close, 14);
            assert!(result.tr.len() == close.len());
            assert!(result.atr.len() == close.len());

            // 验证TR和ATR都是正值
            for i in 0..close.len() {
                assert!(result.tr[i] >= 0.0);
                if i >= 14 {
                    assert!(result.atr[i] >= 0.0);
                }
            }
        }
    }
}